package cease.json;

import java.util.Collection;

import net.sf.json.JSON;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import net.sf.json.JsonConfig;
import net.sf.json.util.CycleDetectionStrategy;

import org.apache.commons.lang.StringUtils;

/**
 * @author dhf
 */
public class JSONUtil {
    @SuppressWarnings("unchecked")
    public static <T> T toBean(JSONObject json, Class<T> clazz) {
        JsonConfig jc = getJsonConfig();
        jc.setRootClass(clazz);
        return (T) JSONObject.toBean(json, jc);
    }

    @SuppressWarnings("unchecked")
    public static <T> Collection<T> toCollection(JSONArray json, Class<T> clazz) {
        JsonConfig jc = getJsonConfig();
        jc.setRootClass(clazz);
        return JSONArray.toCollection(json, jc);
    }

    public static JSON parseJSON(String jsonStr) {
        return parseJSON(jsonStr, null);
    }

    public static JSON parseJSON(String jsonStr, JsonConfig config) {
        jsonStr = StringUtils.trimToNull(jsonStr);
        if (null == jsonStr) {
            throw new IllegalArgumentException("illegal json format");
        }
        JSON result = null;
        if (null == config) {
            config = new JsonConfig();
        }
        if ('[' == jsonStr.charAt(0)
                && ']' == jsonStr.charAt(jsonStr.length() - 1)) {
            result = JSONArray.fromObject(jsonStr, config);
        } else if ('{' == jsonStr.charAt(0)
                && '}' == jsonStr.charAt(jsonStr.length() - 1)) {
            result = JSONObject.fromObject(jsonStr, config);
        } else {
            throw new IllegalArgumentException("illegal json format");
        }
        return result;
    }

    public static JSONArray parseJSONArray(String jsonStr) {
        return parseJSONArray(jsonStr, null);
    }

    public static JSONArray parseJSONArray(String jsonStr, JsonConfig config) {
        JSON json = parseJSON(jsonStr, config);
        if (!json.isArray()) {
            json = JSONArray.fromObject(json);
        }
        return (JSONArray) json;
    }

    public static JsonConfig getJsonConfig() {
        JsonConfig config = new JsonConfig();
        NullValueProcessor nvp = new NullValueProcessor();
        config.registerDefaultValueProcessor(Integer.class, nvp);
        config.registerDefaultValueProcessor(Long.class, nvp);
        config.registerDefaultValueProcessor(Short.class, nvp);
        config.registerDefaultValueProcessor(Float.class, nvp);
        config.registerDefaultValueProcessor(Double.class, nvp);
        config.registerDefaultValueProcessor(String.class, nvp);
        config.registerDefaultValueProcessor(Byte.class, nvp);
        config.registerDefaultValueProcessor(Character.class, nvp);
        config.registerDefaultValueProcessor(Boolean.class, nvp);
        config.setCycleDetectionStrategy(CycleDetectionStrategy.LENIENT);
        config.setPropertySetStrategy(CustomPropertySetStrategy.getInstance());
        return config;
    }

}
